////////////////////////////////////////////////////////////////////
// Programme de recherche de fichier pour Chrono Cross
////////////////////////////////////////////////////////////////////

////////////////////////////////////////////////////////////////////
// Nemesis pour Terminus Traduction (tt_nemesis@yahoo.fr)
// Date de création :		01/08/03
// Dernière modification :	01/08/03
////////////////////////////////////////////////////////////////////

// Entete
#include "Fichiers.h"

// Liste des extensions possibles
// pour des fichiers du patch
#define NB_EXTENSIONS	11
char *extensions[NB_EXTENSIONS] = {
	EXT_TIM,
	EXT_DRP,
	EXT_CPT,
	EXT_LZSS,
	EXT_COORD,
	EXT_DUMP,
	EXT_STR,
	EXT_PSX,
	EXT_SCENAR,
	EXT_TBT,
	EXT_TXT
};

/*------------------------------------------------------------------
  Recherche d'un fichier
--------------------------------------------------------------------
 <- dir = dossier de recherche
 <- fich = fichier à rechercher
 <- ext = extension
 -> fich_complet = nom du fichier trouve, NULL sinon
	ATTENTION ! Pas de libération d'espace implémentée
------------------------------------------------------------------*/
void Fichier_Cherche(char *dir, char *fich,
					 char *ext, char **fich_complet)
{
	// Nom du fichier
	char fich_nom[FICH_NOM_MAX];
	char extension[4];
	// Recherche du fichier
	struct _finddata_t c_file;
    long hFile;

	// Traitement de l'extension
	if (ext!=NULL)
		strcpy(extension,ext);
	else
		strcpy(extension,"*");

	// Obtention du nom complet
	sprintf(fich_nom,"%s%s*.%s",dir,fich,extension);
	hFile = _findfirst(fich_nom, &c_file );

	if (strcmp(c_file.name,"")!=0) {
		*fich_complet=strdup(c_file.name);
	} else
		*fich_complet=NULL;

	_findclose(hFile);
}

/*------------------------------------------------------------------
  Recherche d'un fichier
--------------------------------------------------------------------
 <- dir = dossier de recherche
 <- fich = fichier à rechercher
 -> fich_complet = nom du fichier trouve, NULL sinon
	ATTENTION ! Pas de libération d'espace implémentée
------------------------------------------------------------------*/
void Fichier_Cherche_Ext(char *dir, char *fich, char **fich_complet)
{
	// Indice d'extension
	int i=0;

	// Initialisation
	*fich_complet=NULL;
	// Recherche effective
	while(i<NB_EXTENSIONS
		&& *fich_complet==NULL) {
		Fichier_Cherche(dir,fich,extensions[i],fich_complet);
		i++;
	}
}

/*------------------------------------------------------------------
  Copie d'un fichier quelconque
--------------------------------------------------------------------
 <- fich_in = fichier source
 <- dir_in = répertoire de l'original
 <- fich_out = fichier cible
 <- dir_out = répertoire de la copie
 -> OK si ça s'est bien passé
------------------------------------------------------------------*/
int Fichier_Copie_Std(char *fich_in, char *dir_in,
					  char *fich_out, char *dir_out)
{
	// Fichiers
	FILE *in_f,*out_f;
	// Nom du fichier
	char fich_nom[FICH_NOM_MAX];
	// Recherche du fichier
	struct _finddata_t c_file;
    long hFile;
	// Donnees de copie
	char buffer[FICH_BUFFER];
	int result;

	// Obtention du nom complet
	sprintf(fich_nom,"%s%s",dir_in,fich_in);
	hFile = _findfirst(fich_nom, &c_file );

	// Ouvertures du fichier à copier
	sprintf(fich_nom,"%s%s",dir_in,c_file.name);
	in_f=fopen(fich_nom,"rb");
	// Test d'ouverture
	if (in_f==NULL)
		return ER;
	else {
		// Ouverture en sortie
		if (fich_out==NULL)
			sprintf(fich_nom,"%s%s",dir_out,c_file.name);
		else
			sprintf(fich_nom,"%s%s",dir_out,fich_out);
		out_f=fopen(fich_nom,"wb");
		// Copie du fichier
		while((result=fread(buffer,sizeof(char),
			FICH_BUFFER,in_f))>0)
			fwrite(&buffer,sizeof(char),result,out_f);
		// Fermeture des fichiers
		fclose(in_f);
		fclose(out_f);
	}
	_findclose(hFile);
	return OK;
}

/*------------------------------------------------------------------
  Copie d'un fichier (appelé par Copie_Fichier_In|Out)
--------------------------------------------------------------------
 <- fich = fichier à copier
 <- dir_in = répertoire de l'original
 <- dir_out = répertoire de la copie
 <- ext = extension du fichier
------------------------------------------------------------------*/
void Fichier_Copie(int fich, char *dir_in, char *dir_out, char *ext)
{
	// Nom du fichier
	char fich_in[FICH_NOM_MAX];

	// Obtention du nom complet
	if (ext!=NULL)
		sprintf(fich_in,"%04d*.%s",fich,ext);
	else
		sprintf(fich_in,"%04d*.*",fich);
	// Appel et réalisation de la copie
	if (Fichier_Copie_Std(fich_in,dir_in,NULL,dir_out)!=OK)
		Main_Message_S("Erreur de copie de %s.\n",fich_in,ER);
}

/*------------------------------------------------------------------
  Copie entrante d'un ensemble de fichiers
--------------------------------------------------------------------
 <- fich = ensemble des fichiers déterminés par des délimiteurs
	exemple : 1-4;5;8 = fichiers 1->5 + 8
------------------------------------------------------------------*/
void Fichier_Copie_In (char* fich) {
	// Numéros des fichiers à recompacter
	char* fichs_intervals[FICH_INTER];
	int interval,i;
	// Type d'intervalle
	int result;
	// Bornes
	unsigned _int16 fich_deb,fich_fin,r;
	// Dossier/fichiers
	char* fichiers;
	char* ext;

	// Décomposition dossier/fichiers
	fichiers=strtok(fich,SEPARATEUR);
	ext=strtok(NULL,SEPARATEUR);

	Main_Message_S("Copie entrante de %s...",fichiers,OK);
	// Décomposition des rooms en intervalles
	interval=0; // intervalle actuel
	fichs_intervals[interval]=strtok(fichiers,";");
	do
		interval++;
	while((fichs_intervals[interval]=strtok(NULL,";"))!=NULL);

	// Extension des intervalles
	for(i=0;i<interval;i++) {
		result=sscanf(fichs_intervals[i],"%d-%d",
			&fich_deb,&fich_fin);
		switch (result) {
		case 1:
			Fichier_Copie(fich_deb,DIR_DUMP_IN,DIR_FICH_IN,ext);
			break;
		case 2:
			for (r=fich_deb;r<=fich_fin;r++)
				Fichier_Copie(r,DIR_DUMP_IN,DIR_FICH_IN,ext);
			break;
		default:
			Main_Message_D("Erreur dans l'intervalle %d.\n",i+1,ER);
		}
	}
	Main_OK();
}

/*------------------------------------------------------------------
  Copie sortante d'un ensemble de fichiers
--------------------------------------------------------------------
 <- fich = ensemble des fichiers déterminés par des délimiteurs
	exemple : 1-4;5;8 = fichiers 1->5 + 8
------------------------------------------------------------------*/
void Fichier_Copie_Out (char* fich) {
	// Numéros des fichiers à recompacter
	char* fichs_intervals[FICH_INTER];
	int interval,i;
	// Type d'intervalle
	int result;
	// Bornes
	unsigned _int16 fich_deb,fich_fin,r;
	// Dossier/fichiers
	char* fichiers;
	char* ext;

	// Décomposition dossier/fichiers
	fichiers=strtok(fich,SEPARATEUR);
	ext=strtok(NULL,SEPARATEUR);

	Main_Message_S("Copie sortante de %s...",fichiers,OK);
	// Décomposition des rooms en intervalles
	interval=0; // intervalle actuel
	fichs_intervals[interval]=strtok(fichiers,";");
	do
		interval++;
	while((fichs_intervals[interval]=strtok(NULL,";"))!=NULL);

	// Extension des intervalles
	for(i=0;i<interval;i++) {
		result=sscanf(fichs_intervals[i],"%d-%d",
			&fich_deb,&fich_fin);
		switch (result) {
		case 1:
			Fichier_Copie(fich_deb,DIR_FICH_OUT,DIR_DUMP_OUT,ext);
			break;
		case 2:
			for (r=fich_deb;r<=fich_fin;r++)
				Fichier_Copie(r,DIR_FICH_OUT,DIR_DUMP_OUT,ext);
			break;
		default:
			Main_Message_D("Erreur dans l'intervalle %d.\n",i+1,ER);
		}
	}
	Main_OK();
}

/*------------------------------------------------------------------
  Complétion d'un fichier pour qu'il passe sur PSX
--------------------------------------------------------------------
 <- fich = fichier à compléter
------------------------------------------------------------------*/
void Fichier_Completer(char *fich)
{
	// Fichier
	FILE *f;

	f = fopen(fich,"rb+");
	// Test d'ouverture
	if (f==NULL)
		Main_Message_S("Impossible de completer %s.\n",fich,ER);
	else {
		fseek(f,0L,SEEK_END);
		// Complétion effective
		while(ftell(f)%4!=0)
			fputc(FICH_COMPLETION,f);
		fclose(f);
	}
}
